package com.mybatis.dialog;

import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentValidator;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.psi.PsiClass;
import com.intellij.ui.EditorTextFieldWithBrowseButton;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import com.mybatis.state.ProjectState;
import com.mybatis.utils.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TkConfigDialog implements Disposable {
    private final EditorTextFieldWithBrowseButton mappersCombo;
    private JCheckBox tkMapperCheckBox;
    private JPanel mappersPanel;
    private JPanel root;
    private JCheckBox forceAnnotationCheckBox;
    private JCheckBox caseSensitiveCheckBox;

    public TkConfigDialog(Project project, ProjectState projectState) {
        $$$setupUI$$$();
        this.mappersCombo = new EditorTextFieldWithBrowseButton(project, true);
        this.mappersCombo.setText("tk.mybatis.mapper.common.Mapper");
        this.mappersCombo.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                TreeClassChooserFactory treeClassChooserFactory = TreeClassChooserFactory.getInstance(project);
                TreeClassChooser treeClassChooser = treeClassChooserFactory.createAllProjectScopeChooser("Choose Tk Mapper Mapper Super Class");
                treeClassChooser.showDialog();
                PsiClass psiClass = treeClassChooser.getSelected();
                if (psiClass != null) {
                    mappersCombo.setText(psiClass.getQualifiedName());
                }
            }
        });
        initProjectStateValue(projectState);
        initBuildComponents();
        initValidator();
    }

    public void setConfig(ProjectState projectState) {
        initProjectStateValue(projectState);
    }

    private void initProjectStateValue(ProjectState projectState) {
        this.tkMapperCheckBox.setSelected(projectState.isUserTkMapper());
        this.mappersCombo.setEnabled(projectState.isUserTkMapper());
        this.forceAnnotationCheckBox.setEnabled(projectState.isUserTkMapper());
        this.caseSensitiveCheckBox.setEnabled(projectState.isUserTkMapper());
        this.forceAnnotationCheckBox.setSelected(projectState.isForceAnnotation());
        this.caseSensitiveCheckBox.setSelected(projectState.isCaseSensitive());
    }

    private void initBuildComponents() {
        GridConstraints gridConstraints = new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false);
        this.mappersPanel.add(this.mappersCombo, gridConstraints);
        this.tkMapperCheckBox.addActionListener(e -> {
            mappersCombo.setEnabled(tkMapperCheckBox.isSelected());
            forceAnnotationCheckBox.setEnabled(tkMapperCheckBox.isSelected());
            caseSensitiveCheckBox.setEnabled(tkMapperCheckBox.isSelected());
        });
    }

    private void initValidator() {
        new ComponentValidator(this).withValidator(() -> StringUtils.isBlank(this.mappersCombo.getText()) ? new ValidationInfo("Choose tk mappers", this.mappersCombo) : null)
                .withOutlineProvider(ComponentValidator.CWBB_PROVIDER).installOn(this.mappersCombo);
        this.mappersCombo.getChildComponent().getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void documentChanged(@NotNull DocumentEvent event) {
                ComponentValidator.getInstance(mappersCombo).ifPresent(ComponentValidator::revalidate);
            }
        });
    }

    public boolean doValidate() {
        if (this.tkMapperCheckBox.isSelected() && StringUtils.isBlank(mappersCombo.getText())) {
            ComponentValidator.getInstance(this.mappersCombo).ifPresent(ComponentValidator::revalidate);
            return false;
        }
        return true;
    }


    public void initProjectState(ProjectState projectState) {
        projectState.setUserTkMapper(this.tkMapperCheckBox.isSelected());
        projectState.setTkMappers(this.mappersCombo.getText());
        projectState.setCaseSensitive(this.caseSensitiveCheckBox.isSelected());
        projectState.setForceAnnotation(this.forceAnnotationCheckBox.isSelected());
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        root = new JPanel();
        root.setLayout(new GridLayoutManager(4, 1, new Insets(0, 0, 0, 0), -1, -1));
        final Spacer spacer1 = new Spacer();
        root.add(spacer1, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1));
        root.add(panel1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        tkMapperCheckBox = new JCheckBox();
        tkMapperCheckBox.setText("tk.mapper");
        panel1.add(tkMapperCheckBox, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final Spacer spacer2 = new Spacer();
        panel1.add(spacer2, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1));
        root.add(panel2, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        final JLabel label1 = new JLabel();
        label1.setText("mappers");
        panel2.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        mappersPanel = new JPanel();
        mappersPanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
        panel2.add(mappersPanel, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        final JPanel panel3 = new JPanel();
        panel3.setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1));
        root.add(panel3, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        forceAnnotationCheckBox = new JCheckBox();
        forceAnnotationCheckBox.setText("forceAnnotation");
        forceAnnotationCheckBox.setToolTipText("是否强制生成注解");
        panel3.add(forceAnnotationCheckBox, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        caseSensitiveCheckBox = new JCheckBox();
        caseSensitiveCheckBox.setText("caseSensitive");
        caseSensitiveCheckBox.setToolTipText("是否区分大小写");
        panel3.add(caseSensitiveCheckBox, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return root;
    }

    @Override
    public void dispose() {
        root.removeAll();
    }
}
